#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	FILE *fd;
	char version[100];
	char processor [100];
	char processor_exact[50][100];
	char time[100];
	int n = 0;
	
	char stats_exact[15][100];
	char stat [100];
	
	char *timeSpent[15];
	char *times;
	
	char mem_exact[50][100];
	char mem[100];  
    int projectpart;
    int timebetweenscans;
    int totaltime;
	
    printf("Enter a version of the program to execute (1, 2, or 3): ");
    scanf("%i", &projectpart);
    
    if(projectpart == 3){
		printf("Enter the time between samples: ");
		scanf("%i", &timebetweenscans);
		printf("Enter the total time to take samples: ");
		scanf("%i", &totaltime);}
	
    
	//finding the kernel version:  proc/sys/kernel/version
	fd = fopen( "/proc/sys/kernel/version", "r");
	//Reads the entire contents od file /proc/sys/kernel/version
	while(fgets(version, 100, fd)!=NULL)
		printf("Version:\t%s\n", version);
	fclose (fd);
	
	//finding the processor type: proc/cpuinfo
	fd = fopen ("/proc/cpuinfo", "r");
	n = 0;
	//Reads the entire contents of file proc/cpuinfo
	while ((fgets(processor, 100, fd))!=NULL){
		//processor_exact[n][100] = processor[100];
		strcpy(processor_exact[n++], processor);
	}
	printf("%s\n", processor_exact[4]);
	fclose(fd);
	
	//finding the Uptime & Idle Time: proc/uptime
	fd = fopen("/proc/uptime", "r");
	//Reads the entire contents od file proc/uptime
	while((fgets(time, 100, fd)!=NULL))
		printf("UpTime:\t%s\n", time);
	fclose(fd);
	
	
    if((projectpart == 2) || (projectpart ==3)){
    	//finding the time spent it User Mode, Kernel mode and Idle of processor: proc/stats
    	fd = fopen("/proc/stat", "r");
    	n = 0;
		//Reads the entire contents of file proc/stat and stores is line-by-line in stats_exact[]
    	while((fgets(stat, 100, fd)!=NULL)){
			strcpy(stats_exact[n++], stat);
    	}
    	fclose(fd);
		
		/*Duplicates the first line of proc/stat and breaks it into seperate strings. Select strings                	from the first line need to be displayed*/
    	strcpy(stat, stats_exact[0]);
		//strsep(stats_exact[0], " ");
		//times = &&(stats_exact[0]);   
		
		//Need(s) free() to be implemented
    	times = (char *) malloc(100);   
    	times = stat;
		
		//Need(s) free() to be implemented
    	n = 0;
    	timeSpent[n] = (char *) malloc(100);
    	while( (timeSpent[n] = strsep(&times, " ")) != NULL){
			if( n < sizeof(timeSpent)-1 )
				timeSpent[++n] = (char *) malloc(100);
			else
				break;
    	}
		
    	printf("%s\n", stats_exact[0]);
    	printf("Time (units: USER_HZ[~1/100ths second]) Spent in :\n");
		
    	printf("\tUserMode: %s \n\tKernelMode: %s \n\tIdleTime: %s\n", timeSpent[2],timeSpent[4], timeSpent[5] );
		
		
		
    	printf("\nContext Swithces, Time of Last Boot, Processes created since Boot\n\n");
    	printf("%s\n", stats_exact[8]);
    	printf("%s\n", stats_exact[9]);
    	printf("%s\n", stats_exact[10]);
		int c;
		/*
		 //Memory Deallocation
		 free(times);
		 times=NULL;
		 for(c=0; c<n; c++){
		 free(timeSpent[c]);
		 timeSpent[c] = NULL;
		 }	*/
		// Could not malloc without memory leak, using dummy values to store values in between desired values
		int dummy1;
		int dummy2;
		char dummy3[10];
		int num_reads=0;
		int num_writes=0;
		int readtemp;
		int dummy4;
		int dummy5;
		int dummy6;
		int writetemp;
		int dummy7;
		int dummy8;
		int dummy9;
		int dummy10;
		int dummy11;
		int dummy12;
		char buffer[100];
		fd=fopen("/proc/diskstats", "r");
		while(fgets(buffer, 100,fd) != NULL){
			sscanf(buffer, "%i %i %s %i %i %i %i %i %i %i %i %i %i %i", &dummy1, &dummy2, &dummy3, &readtemp, &dummy4, &dummy5, &dummy6, &writetemp, &dummy7, &dummy8, &dummy9, &dummy10, &dummy11, &dummy12);
			num_reads = num_reads+readtemp;
			num_writes= num_writes+writetemp;}
		printf("Number of read requests: %i\n", num_reads);
		printf("Number of write requests: %i\n", num_writes);
		fclose(fd);
		
    }
	
    if (projectpart ==3){
    	//finding the Configured Memory and Currently Available Memory: /proc/meminfo
    	fd = fopen("/proc/meminfo", "r");
    	n = 0;
		//Reads the entire contents od file proc/meminfo and stores it line-by-line in mem_exact[]
    	while((fgets(mem, 100, fd) != NULL)){
			strcpy(mem_exact[n++], mem);
    	}
    	fclose(fd);
		
		//Outputs the first and second lines contained in proc/meminfo
    	printf("Memory :\n");   
    	printf("%s\n%s\n", mem_exact[0], mem_exact[1]);
    	//printf("Configured: %s \nCurrently Available: %s \n", mem_exact[0], mem_exact[1]);
		
		float load;
		int count=0;
		do{
			fd = fopen("/proc/loadavg", "r");
			fscanf(fd, "%f", &load);
			printf( "%f\n", load);
			sleep(timebetweenscans);
			count++;
			fclose(fd);
		} while(count <= (totaltime/timebetweenscans));	 
    }
	return 0;
}

